package study.db.postgresql.support.type;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.*;

import java.sql.*;

/**
 * https://blog.csdn.net/qq_26664043/article/details/136358934
 * https://blog.csdn.net/qq_41266196/article/details/135382813
 */
@Slf4j
//@MappedTypes({Object[].class})
//@MappedJdbcTypes({JdbcType.ARRAY})
public class ArrayTypeHandler extends BaseTypeHandler<Object[]> {

    private static final String TYPE_NAME_VARCHAR = "varchar";
    private static final String TYPE_NAME_INTEGER = "integer";
    private static final String TYPE_NAME_BOOLEAN = "boolean";
    private static final String TYPE_NAME_NUMERIC = "numeric";
    private static final String TYPE_NAME_LONG = "int8";

    /**
     * 用于设置 PreparedStatement 对象的指定参数
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int parameterIndex, Object[] parameter, JdbcType jdbcType) throws SQLException {

        log.info("sfdsdfsd");
        String typeName = null;
        if (parameter instanceof Integer[]) {
            typeName = TYPE_NAME_INTEGER;
        } else if (parameter instanceof String[]) {
            typeName = TYPE_NAME_VARCHAR;
        } else if (parameter instanceof Boolean[]) {
            typeName = TYPE_NAME_BOOLEAN;
        } else if (parameter instanceof Double[]) {
            typeName = TYPE_NAME_NUMERIC;
        } else if (parameter instanceof Long[]) {
            typeName = TYPE_NAME_LONG;
        }

        if (typeName == null) {
            throw new TypeException("ArrayTypeHandler parameter typeName error, your type is " + parameter.getClass().getName());
        }

        // 这3行是关键的代码，创建 Array，然后 ps.setArray(i, array) 就可以了
        Connection conn = ps.getConnection();
        Array array = conn.createArrayOf(typeName, parameter);
        ps.setArray(parameterIndex, array);
    }

    /**
     * 根据 列名 从结果集中获取数据
     */
    @Override
    public Object[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
        log.info("ffffffffffffff");
        return getArray(rs.getArray(columnName));
    }

    /**
     * 根据 列索引 从结果集中获取数据
     */
    @Override
    public Object[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        log.info("eeeeeeeeeeeeeee");
        return getArray(rs.getArray(columnIndex));
    }

    /**
     * 根据 列索引 从存储过程的结果集中获取数据
     */
    @Override
    public Object[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return getArray(cs.getArray(columnIndex));
    }

    private Object[] getArray(Array array) {
        if (array == null) {
            return null;
        }
        try {
            return (Object[]) array.getArray();
        } catch (Exception e) {
        }
        return null;
    }
}
